package com.dsteiner.widgets.client.controller;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import com.dsteiner.widgets.client.SuggestBoxWidget.Suggestion;
import com.dsteiner.widgets.client.Widgets.IFocusPanel;
import com.dsteiner.widgets.client.Widgets.IHTML;
import com.dsteiner.widgets.client.Widgets.ILazyWidget;
import com.dsteiner.widgets.client.Widgets.IWidget;
import com.dsteiner.widgets.client.Widgets.WidgetListenerAdapter;
import com.dsteiner.widgets.client.model.SuggestBoxModel;
import com.dsteiner.widgets.client.model.SuggestionModel;
import com.dsteiner.widgets.client.resources.WidgetsResources;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;

public class SuggestionController {

	private SuggestionModel suggestionModel;
	private SuggestBoxModel suggestBoxModel;
	private ILazyWidget suggestionWidget;
	private IHTML html;

	public void registerFocusPanel(IFocusPanel focusPanel) {
		focusPanel.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				suggestBoxModel.setChoosenSuggestion(suggestionModel);
			}
		});
	}

	public void registerHtml(final IHTML html) {
		this.html = html;
		html.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				suggestBoxModel.setChoosenSuggestion(suggestionModel);
			}
		});
		html.addMouseOverHandler(new MouseOverHandler(){
			public void onMouseOver(MouseOverEvent event) {
				suggestBoxModel.setSelectedSuggestion(suggestionModel);
			}
		});
		html.addMouseOutHandler(new MouseOutHandler(){
			public void onMouseOut(MouseOutEvent event) {
				suggestBoxModel.setSelectedSuggestion(null);
			}
		});
	}

	public void registerSuggestBoxModel(SuggestBoxModel suggestBoxModel) {
		this.suggestBoxModel = suggestBoxModel;
		suggestBoxModel.addPropertyChangeListener("selectedSuggestion", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateStylename();
			}
		});
		suggestBoxModel.addPropertyChangeListener("text", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateHtml();
				updateAvailability();
			}
		});
	}

	public void registerSuggestionModel(SuggestionModel suggestionModel) {
		this.suggestionModel = suggestionModel;
		suggestionModel.addPropertyChangeListener("suggestion", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateHtml();
				updateAvailability();
			}
		});
		suggestionModel.addPropertyChangeListener("visible", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				updateVisibility();
			}
		});
	}

	public void registerSuggestionWidget(ILazyWidget suggestionWidget) {
		this.suggestionWidget = suggestionWidget;
		suggestionWidget.addWidgetListener(new WidgetListenerAdapter() {
			@Override
			public void onAttach(IWidget widget) {
				updateStylename();
				updateHtml();
				updateAvailability();
			}
		});
	}

	private void updateAvailability() {
		Suggestion suggestion = suggestionModel.getSuggestion();
		String suggestionText = suggestion != null ? suggestion.getDisplayText() : null;
		String text = suggestBoxModel.getText();
		suggestionModel.setVisible(text != null && suggestionText != null && 
				suggestionText.toLowerCase().startsWith(text.toLowerCase()));
	}

	private void updateHtml() {
		Suggestion suggestion = suggestionModel.getSuggestion();
		if(suggestion == null)
			return;
		
		String suggestionText = suggestion.getDisplayText();
		String text = suggestBoxModel.getText();
		String htmlText = "";
		if(text != null && suggestionText.startsWith(text)){
			htmlText = "<strong>"+text+"</strong>";
			htmlText += suggestionText.replace(text, "");
		}
		else
			htmlText = suggestionText;
		
		html.setHTML(htmlText);
	}

	private void updateStylename() {
		suggestionWidget.setStyleName(WidgetsResources.INSTANCE.css().suggestionWidget());
		if(suggestionModel.equals(suggestBoxModel.getSelectedSuggestion()))
			suggestionWidget.addStyleName(WidgetsResources.INSTANCE.css().suggestionWidgetSelected());
	}

	private void updateVisibility() {
		suggestionWidget.setVisible(suggestionModel.isVisible());
	}
}